Skip to content

넘을 수 없는 선

스프라이트가 선을 넘을 수 없도록 막는 방법을 알아봅니다. 이 기능은 DetectLineCrossing Hook을 사용합니다.

만들어볼 맵은 다음과 같습니다. 아래 맵은 브라우저에서 Stadium을 통해 직접 그려졌습니다.

  • 키보드를 사용하여 스프라이트를 움직일 수 있습니다.
  • 스프라이트는 선을 넘을 수 없습니다.

선을 통과할 수 없게 만들기

DetectLineCrossingblockMove 옵션을 true로 설정하면 스프라이트가 선을 통과할 수 없습니다.

js
const detector = new DetectLineCrossing({
  blockMove: true, 
});

SensorLine으로 네모 박스 만들기

SensorLine은 선을 그리는 스프라이트입니다. SensorLine으로 네모 박스를 만들어봅니다.

또한 DetectLineCrossing가 선을 감지할 수 있도록 SensorLinedetector.targetTag 태그를 추가합니다.

js
const lines = [
  { p1: { left: 100, top: 100 }, p2: { left: 100, top: 280 } },
  { p1: { left: 100, top: 280 }, p2: { left: 280, top: 280 } },
  { p1: { left: 280, top: 280 }, p2: { left: 280, top: 100 } },
  { p1: { left: 280, top: 100 }, p2: { left: 100, top: 100 } },
];

for (const line of lines) {
  const sensorLine = new SensorLine(line);

  sensorLine.tags.push(detector.targetTag);
  stadium.add(sensorLine);
}

키보드로 스프라이트 움직이기

Animate를 사용하여 스프라이트를 움직일 수 있습니다.

js
const animate = new Animate();

키보드 이벤트를 사용하여 스프라이트를 움직입니다.

js
addEventListener("keydown", (e) => {
  switch (e.key) {
    case "ArrowUp":
      animate.moveBy(0, -20, 100);
      break;
    case "ArrowDown":
      animate.moveBy(0, 20, 100);
      break;
    case "ArrowLeft":
      animate.moveBy(-20, 0, 100);
      break;
    case "ArrowRight":
      animate.moveBy(20, 0, 100);
      break;
  }
});

선을 통과했을 때 이벤트 발생시키기

DetectLineCrossingpubsub을 사용하여 선을 통과했을 때 이벤트를 발생시킬 수 있습니다.

js
detector.pubsub.sub("blocked", () => {
  alert("막혔습니다!");
});

전체 코드

js
const lines = [
  { p1: { left: 100, top: 100 }, p2: { left: 100, top: 280 } },
  { p1: { left: 100, top: 280 }, p2: { left: 280, top: 280 } },
  { p1: { left: 280, top: 280 }, p2: { left: 280, top: 100 } },
  { p1: { left: 280, top: 100 }, p2: { left: 100, top: 100 } },
];

const detector = new DetectLineCrossing({
  blockMove: true,
});

for (const line of lines) {
  const sensorLine = new SensorLine(line);

  sensorLine.tags.push(detector.targetTag);
  stadium.add(sensorLine);
}

const picture = new ImageSprite({
  src: "https://picsum.photos/200",
  size: {
    width: 40,
    height: 40,
  },
  position: {
    left: 160,
    top: 220,
  },
});

const animate = new Animate();

detector.pubsub.sub("blocked", () => {
  alert("막혔습니다!");
});

picture.use([detector, animate]);

stadium.add(picture);

addEventListener("keydown", (e) => {
  switch (e.key) {
    case "ArrowUp":
      animate.moveBy(0, -20, 100);
      break;
    case "ArrowDown":
      animate.moveBy(0, 20, 100);
      break;
    case "ArrowLeft":
      animate.moveBy(-20, 0, 100);
      break;
    case "ArrowRight":
      animate.moveBy(20, 0, 100);
      break;
  }
});